package com.systop.ltbook.order.webapp;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.hibernate.criterion.MatchMode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;

import com.systop.cms.utils.PageUtil;
import com.systop.common.modules.security.user.LoginUserService;
import com.systop.common.modules.security.user.model.User;
import com.systop.core.dao.support.Page;
import com.systop.core.webapp.struts2.action.DefaultCrudAction;
import com.systop.ltbook.book.model.Book;
import com.systop.ltbook.order.OrderConstants;
import com.systop.ltbook.order.cart.model.Cart;
import com.systop.ltbook.order.cart.model.CartItem;
import com.systop.ltbook.order.model.OrderForm;
import com.systop.ltbook.order.model.OrderItem;
import com.systop.ltbook.order.service.OrderFormManager;
import com.systop.ltbook.order.service.OrderItemManager;
import com.systop.ltbook.order.util.DoubleUtils;

@SuppressWarnings("serial")
@Controller
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class OrderFormAction extends
		DefaultCrudAction<OrderForm, OrderFormManager> {
	/**
	 * 登录用户信息管理类
	 */
	@Autowired
	private LoginUserService loginUserService;
	/** 订单项Manager */
	@Autowired
	private OrderItemManager orderItemManager;
	// 下单日期查询起点
	private Date createBeginDate;
	// 下单日期查询终点
	private Date createEndDate;
	// 支付日期查询起点
	private Date payBeginDate;
	// 支付日期查询终点
	private Date payEndDate;

	// 订单项,以接收后台修改图书数量的ajax请求json数据
	private OrderItem orderItem = new OrderItem();

	private Map<String, String> jsonResult = new HashMap<String, String>();
	// 状态名称和值的Map集合
	private Map<String, String> statusMap = new LinkedHashMap<String, String>();
	// 应用于前台界面的状态map集合,主要是去掉了"取消/删除"
	private Map<String, String> frontStatusMap = new LinkedHashMap<String, String>();

	/**
	 * index方法
	 */
	@SuppressWarnings("unchecked")
	@Override
	public String index() {
		Page page = PageUtil.getPage(getPageNo(), getPageSize());
		StringBuffer buf = new StringBuffer(
				"from OrderForm orf where orf.status <> 7  ");
		List args = new ArrayList();

		buildQueryCondition(buf, args);
		page = getManager().pageQuery(page, buf.toString(), args.toArray());
		restorePageData(page);

		return INDEX;
	}

	/**
	 * 统计方法
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String stat() {
		Page page = PageUtil.getPage(getPageNo(), getPageSize());
		StringBuffer buf = new StringBuffer(
				"from OrderForm orf where orf.status <> 7  ");
		List args = new ArrayList();

		buildQueryCondition(buf, args);
		page = getManager().pageQuery(page, buf.toString(), args.toArray());
		restorePageData(page);
		
		List list = getManager().query(buf.toString(), args.toArray());
		// 数量
		int count = list.size();
		getRequest().setAttribute("count", count);
		// 总金额
		Double total = stateTotal(list);
		getRequest().setAttribute("total", total);

		return "stat";
	}

	/**
	 * 编辑订单及订单明细
	 */
	@SuppressWarnings("unchecked")
	@Override
	public String edit() {
		setModel(getManager().get(getModel().getId()));
		// buildStatusMap();
		String hql = "from OrderItem oi where oi.orderForm.id = ?";
		List args = new ArrayList();
		args.add(getModel().getId());

		Page page = PageUtil.getPage(getPageNo(), getPageSize());
		page = getManager().pageQuery(page, hql, args.toArray());
		restorePageData(page);
		// 应用于后台编辑订单界面的状态map集合,主要是去掉了"取消/删除"
		Map<String, String> adminEditStatusMap = new LinkedHashMap<String, String>();
		adminEditStatusMap.putAll(OrderConstants.ADMIN_EDIT_ORDER_STATE);
		getRequest().setAttribute("adminEditStatusMap", adminEditStatusMap);

		return super.edit();
	}

	/**
	 * 保存操作
	 */
	@Override
	public String save() {
		// 如果是支付并且日期为空,则审定支付日期为当前日期
		if (OrderConstants.ORDER_STATE_PAYED.equals(getModel().getStatus())
				&& getModel().getPayDate() == null) {
			getModel().setPayDate(new Date());
		}
		return super.save();
	}

	/**
	 * 生成订单
	 * 
	 * @return
	 */
	public String placeOrder() {
		// 得到当前登录用户,以生成订单时关联到订单用户
		User user = loginUserService.getLoginUser(getRequest());
		HttpSession session = getRequest().getSession();
		if (session != null) {
			Cart cart = (Cart) session.getAttribute("cart");
			if (cart != null) {
				OrderForm order = new OrderForm();
				order.setSn(getManager().getNextSn());
				order.setUser(user);
				// order.setDescn("");
				order.setStatus(OrderConstants.ORDER_STATE_NOT_AUDIT);
				order.setCreateDate(new Date());
				order.setMoney(cart.getTotal());

				getManager().save(order);

				Iterator<Integer> itr = cart.getItems().keySet().iterator();
				while (itr.hasNext()) {
					CartItem cItm = cart.getItems().get(itr.next());
					Book book = cItm.getBook();
					OrderItem oItm = new OrderItem();
					oItm.setBook(book);
					oItm.setTruePrice(book.getPrice());// 默认以图书单价作为执行单价
					oItm.setCount(cItm.getCount());
					oItm.setMoney(cItm.getAmount());
					oItm.setDescn("");
					oItm.setOrderForm(order);
					order.getItems().add(oItm);

					orderItemManager.save(oItm);
				}
				setModel(order);
				// 清空购物车
				cart.clear();
				// 从session中删除cart
				session.removeAttribute("cart");

			}
		}

		return SUCCESS;
	}

	/**
	 * 取消订单,前台取消
	 * 
	 * @return 页面转向
	 */
	public String cancelOrder() {
		OrderForm of = getManager().get(getModel().getId());
		of.setStatus(OrderConstants.ORDER_STATE_CANCELED);
		save();
		// 前台在查看订单列表时取消订单
		if ("frontIndex".equals(getRequest().getParameter("arg"))) {
			// 继续查看订单
			return "goFrontIndex";
		} else {
			// 下订单,查看订单取消订单-->继续购书
			return "continue";
		}
	}

	/**
	 * 后台修改订单中订单明细数量
	 * 
	 * @return
	 */
	public String modifyOrderItem() {
		OrderItem oi = orderItemManager.get(orderItem.getId());
		oi.setCount(orderItem.getCount());
		oi.setTruePrice(orderItem.getTruePrice());
		oi.setMoney(oi.getTruePrice() * oi.getCount());
		orderItemManager.save(oi);

		OrderForm of = oi.getOrderForm();
		reCalculateMondy(of);
		getManager().save(of);
		jsonResult.put("orderMoney", String.valueOf(of.getMoney()));

		return "jsonRst";
	}

	/**
	 * 后台删除订单项
	 * 
	 * @return
	 */
	public String removeCartItem() {
		OrderItem oi = orderItemManager.get(orderItem.getId());
		OrderForm of = oi.getOrderForm();
		of.getItems().remove(oi);
		orderItemManager.remove(oi);

		reCalculateMondy(of);
		getManager().save(of);
		jsonResult.put("orderMoney", String.valueOf(of.getMoney()));

		return "jsonRst";
	}

	/**
	 * 重新计算订单金额
	 * 
	 * @param of
	 */
	private void reCalculateMondy(OrderForm of) {
		Double money = 0d;
		for (OrderItem oItem : of.getItems()) {

			money += oItem.getMoney();
		}

		of.setMoney(DoubleUtils.roundDouble(money, 2));
	}

	/**
	 * 审核订单
	 * 
	 * @return
	 */
	public String audit() {
		OrderForm of = getManager().get(getModel().getId());
		of.setStatus(OrderConstants.ORDER_STATE_PASSED);
		save();

		return index();
	}

	/**
	 * 后台操作订单,包括: 支付/发货/结单
	 * 
	 * @return
	 */
	public String operation() {
		setModel(getManager().get(getModel().getId()));
		OrderForm oForm = getManager().get(getModel().getId());
		// 未审核-->已审核未支付
		if (OrderConstants.ORDER_STATE_NOT_AUDIT.equals(getModel().getStatus())) {
			oForm.setStatus(OrderConstants.ORDER_STATE_PASSED);
			// 未支付-->已支付
		} else if (OrderConstants.ORDER_STATE_PASSED.equals(getModel()
				.getStatus())) {
			oForm.setStatus(OrderConstants.ORDER_STATE_PAYED);
			// 已支付未发货-->已发货
		} else if (OrderConstants.ORDER_STATE_PAYED.equals(getModel()
				.getStatus())) {
			oForm.setStatus(OrderConstants.ORDER_STATE_SEND);
			// 已发货-->已结单
		} else {
			oForm.setStatus(OrderConstants.ORDER_STATE_FINISHED);
		}

		save();

		return SUCCESS;
	}

	/**
	 * 前台根据用户得到订单
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String frontIndex() {
		int pageNo = 1;
		String pageNoStr = getRequest().getParameter("pageNo");
		if (StringUtils.isNotBlank(pageNoStr)) {
			pageNo = Integer.valueOf(pageNoStr);
		}

		// 得到当前登录用户
		User user = loginUserService.getLoginUser(getRequest());
		Assert.notNull(user);
		Page page = PageUtil.getPage(pageNo, 5);

		StringBuffer hql = new StringBuffer(
				"from OrderForm orf where orf.user.id = ? and orf.status != ? ");
		List args = new ArrayList();
		args.add(user.getId());
		args.add(OrderConstants.ORDER_STATE_REMOVE);
		buildQueryCondition(hql, args);
		page = getManager().pageQuery(page, hql.toString(), args.toArray());
		restorePageData(page);

		// 应用于前台界面的状态map集合,主要是去掉了"取消/删除"
		Map<String, String> frontStatusMap = new LinkedHashMap<String, String>();
		frontStatusMap.putAll(OrderConstants.FRONT_ORDER_STATE);
		getRequest().setAttribute("frontStatusMap", frontStatusMap);

		getRequest().setAttribute("myOrders", page);

		return "frontIndex";
	}

	/**
	 * 根据id查看订单
	 * 
	 * @return
	 */
	public String viewOrder() {
		setModel(getManager().get(getModel().getId()));
		return "viewOrder";
	}

	/**
	 * 修改订单
	 * 
	 * @return
	 */
	public String modifyOrder() {

		return "viewOrder";
	}

	/**
	 * 删除订单,后台删除
	 */
	@Override
	public String remove() {
		OrderForm of = getManager().get(getModel().getId());
		// 置订单状态标识为删除状态
		of.setStatus(OrderConstants.ORDER_STATE_REMOVE);

		return save();
	}

	/**
	 * 构建查询条件,前台后台都需要构建类似的查询条件
	 * 
	 * @param buf
	 * @param args
	 */

	@SuppressWarnings("unchecked")
	private void buildQueryCondition(StringBuffer buf, List args) {
		// 订单号
		if (StringUtils.isNotBlank(getModel().getSn())) {
			buf.append("and orf.sn like ? ");
			args.add(MatchMode.ANYWHERE.toMatchString(getModel().getSn()));
		}
		// 订单用户
		if (getModel().getUser() != null
				&& StringUtils.isNotBlank(getModel().getUser().getName())) {
			buf.append("and orf.user.name like ? ");
			args.add(MatchMode.ANYWHERE.toMatchString(getModel().getUser()
					.getName()));
		}
		// 订单创建时间--起
		if (createBeginDate != null) {
			buf.append("and orf.createDate >= ? ");
			args.add(createBeginDate);
		}
		// 订单创建时间--止
		if (createEndDate != null) {
			buf.append("and orf.createDate <= ? ");
			args.add(createEndDate);
		}
		// 订单支付时间--起
		if (payBeginDate != null) {
			buf.append("and orf.payDate >= ? ");
			args.add(payBeginDate);
		}
		// 订单支付时间--止
		if (payEndDate != null) {
			buf.append("and orf.payDate <= ? ");
			args.add(payEndDate);
		}
		// 订单状态
		if (StringUtils.isNotBlank(getModel().getStatus())) {
			buf.append("and orf.status = ? ");
			args.add(getModel().getStatus());
		}
	}

	/**
	 * 根据订单当前状态,构建状态名称和值的Map集合
	 * 
	 */
	@SuppressWarnings("unused")
	private void buildStatusMap() {
		statusMap.clear();
		// 未审核
		if (OrderConstants.ORDER_STATE_NOT_AUDIT.equals(getModel().getStatus())) {
			// 审核通过/未通过
			statusMap.put(OrderConstants.ORDER_STATE_PASSED,
					OrderConstants.ORDER_STATE_PASSED_STR);
			statusMap.put(OrderConstants.ORDER_STATE_REJECT,
					OrderConstants.ORDER_STATE_REJECT_STR);
			// 审核通过
		} else if (OrderConstants.ORDER_STATE_PASSED.equals(getModel()
				.getStatus())) {
			statusMap.put(OrderConstants.ORDER_STATE_PAYED,
					OrderConstants.ORDER_STATE_PAYED_STR);
			// 已支付
		} else if (OrderConstants.ORDER_STATE_PAYED.equals(getModel()
				.getStatus())) {
			statusMap.put(OrderConstants.ORDER_STATE_SEND,
					OrderConstants.ORDER_STATE_SEND_STR);
			// 已发货
		} else if (OrderConstants.ORDER_STATE_SEND.equals(getModel()
				.getStatus())) {
			statusMap.put(OrderConstants.ORDER_STATE_FINISHED,
					OrderConstants.ORDER_STATE_FINISHED_STR);
		}
	}

	/**
	 * 计算统计总金额
	 * 
	 * @param list
	 *            统计得到的集合
	 * @return 累计集合中各个实体的money属性值得到的总金额
	 */
	private Double stateTotal(List<OrderForm> list) {
		Double total = 0d;
		for (OrderForm oForm : list) {
			total += oForm.getMoney();
		}
		return total;
	}

	public Date getCreateBeginDate() {
		return createBeginDate;
	}

	public void setCreateBeginDate(Date createBeginDate) {
		this.createBeginDate = createBeginDate;
	}

	public Date getCreateEndDate() {
		return createEndDate;
	}

	public void setCreateEndDate(Date createEndDate) {
		this.createEndDate = createEndDate;
	}

	public Date getPayBeginDate() {
		return payBeginDate;
	}

	public void setPayBeginDate(Date payBeginDate) {
		this.payBeginDate = payBeginDate;
	}

	public Date getPayEndDate() {
		return payEndDate;
	}

	public void setPayEndDate(Date payEndDate) {
		this.payEndDate = payEndDate;
	}

	public Map<String, String> getStatusMap() {

		statusMap.putAll(OrderConstants.ORDER_STATE);

		return statusMap;
	}

	public OrderItem getOrderItem() {
		return orderItem;
	}

	public void setOrderItem(OrderItem orderItem) {
		this.orderItem = orderItem;
	}

	public Map<String, String> getJsonResult() {
		return jsonResult;
	}

	public Map<String, String> getFrontStatusMap() {
		frontStatusMap.putAll(OrderConstants.FRONT_ORDER_STATE);
		return frontStatusMap;
	}

	public void setFrontStatusMap(Map<String, String> frontStatusMap) {
		this.frontStatusMap = frontStatusMap;
	}

}
